﻿using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using SmartPlant.Core;
using SmartPlant.Core.Mvvm;
using SmartPlant.Model;
using SmartPlant.Model.DbContext.Biz;
using SmartPlant.Services.Interfaces;
using SmartPlant.WinCore;
using SmartPlant.WinCore.Helper;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows.Forms;
using System.Windows.Input;
using Unity;

namespace SmartPlant.Modules.Base.ViewModels
{
    public class TemplateSettingViewModel : ListRegionViewModel<Report>
    {
        private int _templateType = 0;
        private DelegateCommand<string> _downloadFileCommand;
        private DelegateCommand<string> _uploadFileCommand;
        private DelegateCommand<object> _uploadAllFileCommand;
        private DelegateCommand<object> _batchUploadAllFileCommand;
        private DelegateCommand<object> _autoSpecCreateCommand;
        private DelegateCommand _deleteFileCommand;
        private DelegateCommand _editTemplateCommand;
        private DelegateCommand _editXMLCommand;
        private ITemplateSettingService _templateSettingService;
        //private IAchievementService _achievementService;
        //private IImportUtilityService _importUtilityService;
        private readonly IEventAggregator _eventAggregator;

        public TemplateSettingViewModel(
            IRegionManager regionManager,
            ITemplateSettingService templateSettingService,
            IUnityContainer unityContainer,
            IDialogService dialogService,
            IEventAggregator eventAggregator,
            IAchievementService AchievementService,
            IImportUtilityService importUtilityService
            ) :
            base(regionManager, unityContainer, dialogService)
        {
            //_templateType = templateType;
            _templateSettingService = templateSettingService;
            _eventAggregator = eventAggregator;
            //_achievementService = AchievementService;
            //_importUtilityService = importUtilityService;
        }

        #region UI-binding-data
        /// <summary>
        /// 新建
        /// </summary>
        public ICommand CreateReportCommand
        {
            get
            {
                if (_uploadAllFileCommand != null) return _uploadAllFileCommand;
                _uploadAllFileCommand = new DelegateCommand<object>(onCreateReportCommandAsync);
                return _uploadAllFileCommand;
            }
        }

        /// <summary>
        /// 批量新建模板
        /// </summary>
        public ICommand BatchCreateReportCommand
        {
            get
            {
                if (_batchUploadAllFileCommand != null) return _batchUploadAllFileCommand;
                _batchUploadAllFileCommand = new DelegateCommand<object>(onBatchCreateReportCommandAsync);
                return _batchUploadAllFileCommand;
            }
        }

        /// <summary>
        /// 自动数据表模板创建
        /// </summary>
        public ICommand AutoSpecCreateCommand
        {
            get
            {
                if (_autoSpecCreateCommand != null) return _autoSpecCreateCommand;
                _autoSpecCreateCommand = new DelegateCommand<object>(onAutoSpecCreateCommandAsync);
                return _autoSpecCreateCommand;
            }
        }

        public ICommand UploadFileCommand
        {
            get
            {
                if (_uploadFileCommand != null) return _uploadFileCommand;
                _uploadFileCommand = new DelegateCommand<string>(onUpLoadCommandAsync);
                return _uploadFileCommand;
            }
        }

        public ICommand DownloadFileCommand
        {
            get
            {
                if (_downloadFileCommand != null) return _downloadFileCommand;
                _downloadFileCommand = new DelegateCommand<string>(onDownLoadCommandAsync);
                return _downloadFileCommand;
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        public ICommand DeleteReportCommand
        {
            get
            {
                if (_deleteFileCommand != null) return _deleteFileCommand;
                _deleteFileCommand = new DelegateCommand(onDeleteFileCommandAsync);
                return _deleteFileCommand;
            }
        }
        /// <summary>
        /// 编辑
        /// </summary>
        public ICommand EditReportCommand
        {
            get
            {
                if (_editTemplateCommand != null) return _editTemplateCommand;
                _editTemplateCommand = new DelegateCommand(onEditTemplateCommandAsync);
                return _editTemplateCommand;
            }
        }
        /// <summary>
        /// 编辑XML
        /// </summary>
        public ICommand EditXMLCommand
        {
            get
            {
                if (_editXMLCommand != null) return _editXMLCommand;
                _editXMLCommand = new DelegateCommand(onEditXMLCommandAsync);
                return _editXMLCommand;
            }
        }
        #endregion

        private void onEditTemplateCommandAsync()
        {
            if (SelectObj == null)
            {
                Dialog.ShowAltert("请先选择需要编辑的模板对象！！！");
                return;
            }
            var para = new DialogParameters
            {
                { "ReportID", SelectObj.ReportId.ToString() },
                { "Name", SelectObj.Name },
                { "Parameters", SelectObj.Parameters },
                { "InOrOut", SelectObj.InOrOut },
                { "Type", SelectObj.Type },
                { "Description", SelectObj.Description },
                { "Generatefunc", SelectObj.GenerateFunc },
                { "Sql", SelectObj.SQL },
                { "TemplatePath", SelectObj.TemplatePath }
            };
            Dialog.ShowDialog("TemplateSettingEdit", para,
                d =>
                {
                    if (d.Result == ButtonResult.OK)
                    {
                        OnInitPage(null);
                        _eventAggregator.GetEvent<TemplateChangedEvent>()
                        .Publish((TemplateType)_templateType);
                    }
                });
        }
        private async void onEditXMLCommandAsync()
        {
            if (SelectObj == null)
            {
                Dialog.ShowAltert("请先选择需要编辑的模板对象！！！");
                return;
            }
            string proId = GlobalObject.CurrentProject.ProjId.ToString();

            try
            {
                var postObj = SelectObj.CloneObject();
                postObj.Name += ".xml";
                RESTfulResult<Stream> result = new RESTfulResult<Stream>();
                result = await _templateSettingService.DownloadTemplateFileAsync(proId, postObj);
                if (!result.succeeded)
                {
                    LoggerHelper.Current.Error(result.errors.ToString());
                    Dialog.ShowAltert(result.errors.ToString());
                    return;
                }
                try
                {
                    result.data.Position = 0;
                    var xml = result.data.ToString2();
                    var para = new DialogParameters
                    {
                        { "Name", postObj.Name },
                        { "InOrOut", SelectObj.InOrOut },
                        { "Type", SelectObj.Type },
                        { "TemplatePath", SelectObj.TemplatePath },
                        { "XML", xml }
                    };

                    Dialog.ShowDialog("TemplateSettingEditXML", para,
                        d =>
                        {
                            if (d.Result == ButtonResult.OK)
                            {
                                OnInitPage(null);
                                _eventAggregator.GetEvent<TemplateChangedEvent>()
                                .Publish((TemplateType)_templateType);
                            }
                        });
                }
                catch (Exception x)
                {
                    string msg = $"下载模板文件失败：{x.Message}";
                    LoggerHelper.Current.Error(msg, x);
                    Dialog.ShowAltert(msg);
                }
            }
            catch (Exception x)
            {
                var xMessage = $"获取远程服务器数据失败：{x.Message}！！！";
                LoggerHelper.Current.Error(xMessage, x);
                Dialog.ShowAltert(xMessage);
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        private async void onDeleteFileCommandAsync()
        {
            if (SelectObj == null)
            {
                Dialog.ShowAltert("请先选择需要删除的模板！！！");
                return;
            }
            var areyouok = MessageBox.Show("删除后无法恢复，确定删除吗？", "警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
            if (areyouok == System.Windows.Forms.DialogResult.OK)
            {
                string proId = GlobalObject.CurrentProject.ProjId.ToString();
                var result = await _templateSettingService.DeleteTemplateAsync(proId, _templateType, SelectObj);
                if (result.succeeded)
                {
                    OnInitPage(null);//刷新页面内容
                    _eventAggregator.GetEvent<TemplateChangedEvent>()
                                            .Publish((TemplateType)_templateType);//发布事件，参数为_templateType,索引导入模块有订阅
                }
            }
        }

        private async void onDownLoadCommandAsync(string fileType)
        {
            if (SelectObj == null)
            {
                Dialog.ShowAltert("请先选择需要编辑的模板！！！");
                return;
            }
            string templatename = ".xlsx";
            string fileFilter = "Excel文件 *.xlsx|*.xlsx";
            if (fileType.ToLower() == "xml")
            {
                templatename = ".xml";
                fileFilter = "XML文件 *.xml|*.xml";
            }

            //templatename = SelectObj.Name + templatename;

            string proId = GlobalObject.CurrentProject.ProjId.ToString();

            try
            {
                var postObj = SelectObj.CloneObject();
                postObj.Name += templatename;
                RESTfulResult<Stream> result = new RESTfulResult<Stream>();

                result = await _templateSettingService.DownloadTemplateFileAsync(proId, postObj);

                if (!result.succeeded)
                {
                    LoggerHelper.Current.Error(result.errors.ToString());
                    Dialog.ShowAltert(result.errors.ToString());
                    return;
                }
                var saveFileDialog = new Microsoft.Win32.SaveFileDialog
                {
                    Filter = fileFilter,
                    FileName = postObj.Name,
                };
                using var stream = result.data;
                if (saveFileDialog.ShowDialog() == true)
                {
                    var _fielPath = saveFileDialog.FileName;
                    await FileHelper.WriteFileStreamAsync(stream, _fielPath);
                    var rMessage = "下载模板文件到本地成功，请编辑后重新上传！！！";
                    Dialog.ShowAltert(rMessage);
                    ExplorerFileExtensions.ExplorerFile(_fielPath); //打开目录
                    return;
                }
            }
            catch (Exception x)
            {
                var xMessage = $"获取远程服务器数据失败：{x.Message}！！！";
                LoggerHelper.Current.Error(xMessage, x);
                Dialog.ShowAltert(xMessage);
            }
        }

        private async void onUpLoadCommandAsync(string fileType)
        {
            if (SelectObj == null)
            {
                Dialog.ShowAltert("请先选择需要上传的模板对象！！！");
                return;
            }

            string proId = GlobalObject.CurrentProject.ProjId.ToString();
            string templatename = ".xlsx";
            string fileFilter = "Excel文件(优先xlsx)|*.xlsx;*.xls";
            if (fileType.ToLower() == "xml")
            {
                templatename = ".xml";
                fileFilter = "XML文件 *.xml|*.xml";
            }
            //else
            //{
            //    System.Windows.Forms.MessageBox.Show("请优先选择xlsx格式的文件，若选xls，DI-Intools将帮您转为xlsx，但是某些内容会失真，请悉知！", "提示", System.Windows.Forms.MessageBoxButtons.OK);
            //}
            templatename = SelectObj.Name + templatename;

            var openFileDialog = new Microsoft.Win32.OpenFileDialog
            {
                Filter = fileFilter,
            };

            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    var FilePath = openFileDialog.FileName;
                    try
                    {
                        #region 转xlsx
                        if (FilePath.Contains(".xls") && !FilePath.Contains(".xlsx"))
                        {
                            System.Windows.Forms.MessageBox.Show("请优先选择xlsx格式的文件，若选xls，DI-Intools将帮您转为xlsx，但是某些内容会失真，请悉知！", "提示", System.Windows.Forms.MessageBoxButtons.OK);

                            FilePath = ExcelHelper.xls2xlsx(FilePath.Replace(openFileDialog.SafeFileName, ""), openFileDialog.SafeFileName);
                            using var stream = new FileStream(FilePath, FileMode.Open);
                            bool r = false;

                            r = await _templateSettingService.UploadTemplateFileAsync(proId, SelectObj.Type, stream, templatename, SelectObj.InOrOut);

                            if (r)
                                Dialog.ShowAltert("上传文件至远程服务器成功！！！");
                        }
                        else
                        {
                            using Stream stream = openFileDialog.OpenFile();
                            bool r = false;

                            r = await _templateSettingService.UploadTemplateFileAsync(proId, SelectObj.Type, stream, templatename, SelectObj.InOrOut);

                            if (r)
                                Dialog.ShowAltert("上传文件至远程服务器成功！！！");
                        }
                        #endregion
                    }
                    catch
                    {
                        Dialog.ShowAltert("打开Excel文件失败，文件可能已加密(损坏)或已被其它进程打开。");
                    }

                }
                catch (Exception x)
                {
                    var xMessage = $"上传文件至远程服务器失败：{x.Message}！！！";
                    LoggerHelper.Current.Error(xMessage, x);
                    Dialog.ShowAltert(xMessage);
                }
            }
        }

        /// <summary>
        /// 新建
        /// </summary>
        /// <param name="obj"></param>
        private void onCreateReportCommandAsync(object obj)
        {
            Dialog.ShowDialog("TemplateSettingNew",
                new DialogParameters($"templateType={_templateType}"),
                d =>
                {
                    if (d.Result == ButtonResult.OK)
                    {
                        OnInitPage(null);
                        _eventAggregator.GetEvent<TemplateChangedEvent>()
                        .Publish((TemplateType)_templateType);
                    }
                });
        }

        /// <summary>
        ///批量新建
        /// </summary>
        /// <param name="obj"></param>
        private void onBatchCreateReportCommandAsync(object obj)
        {
            //Dialog.ShowDialog("BatchTemplateSettingNew");
            Dialog.ShowDialog("BatchTemplateSettingNew",
                d =>
                {
                    if (d.Result == ButtonResult.OK)
                    {
                        OnInitPage(null);
                        _eventAggregator.GetEvent<TemplateChangedEvent>()
                        .Publish((TemplateType)_templateType);
                    }
                });
        }

        /// <summary>
        ///自动数据表模板创建
        /// </summary>
        /// <param name="obj"></param>
        private async void onAutoSpecCreateCommandAsync(object obj)
        {
            //Dialog.ShowDialog("BatchTemplateSettingNew");
            while (true)
            {
                OpenFileDialog openFileDialog = new OpenFileDialog
                {
                    Filter = "XML and XLSX files|*.xml;*.xlsx",
                    Multiselect = true,
                    Title = "请选择需要上传的数据表模板文件:"
                };

                if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    var files = openFileDialog.FileNames;
                    var xmlFiles = files.Where(f => f.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)).ToList();
                    var xlsxFiles = files.Where(f => f.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase)).ToList();

                    var xmlFileNames = xmlFiles.Select(f => Path.GetFileNameWithoutExtension(f).ToLower()).ToList();
                    var xlsxFileNames = xlsxFiles.Select(f => Path.GetFileNameWithoutExtension(f).ToLower()).ToList();

                    var unmatchedXmlFiles = xmlFiles.Where(f => !xlsxFileNames.Contains(Path.GetFileNameWithoutExtension(f).ToLower())).ToList();
                    var unmatchedXlsxFiles = xlsxFiles.Where(f => !xmlFileNames.Contains(Path.GetFileNameWithoutExtension(f).ToLower())).ToList();

                    if (!unmatchedXmlFiles.Any() && !unmatchedXlsxFiles.Any()) //Excel和xml文件匹配成功
                    {

                        if (xmlFiles.Count < 1)
                        {
                            Dialog.ShowAltert("请选择数据表模板文件！！！");
                            return;
                        }
                        string proId = GlobalObject.CurrentProject.ProjId.ToString();

                        

                        foreach (var file in xmlFiles)
                        {


                            try
                            {
                                
                                Report report = new Report
                                {
                                    Description = "",
                                    GenerateFunc = "",
                                    Name = Path.GetFileNameWithoutExtension(file),
                                    SQL = "",
                                    TemplatePath = GlobalObject.CurrentProject.ProjName,
                                    Type = TemplateType.SPEC,
                                    Parameters = "",
                                    InOrOut = -1
                                };
                                var r = await _templateSettingService.CreateTemplateAsync(proId, report);

                                if (r.succeeded == true)
                                {
                                    
                                    var fileStream = new FileStream(file, FileMode.Open);
                                    
                                    await _templateSettingService.UploadTemplateFileAsync(proId, report.Type, fileStream, report.Name+".xml", -1);


                                    fileStream = new FileStream(file.ToLower().Replace(".xml",".xlsx"), FileMode.Open);

                                    await _templateSettingService.UploadTemplateFileAsync(proId, report.Type, fileStream, report.Name + ".xlsx", -1);

                                   

                                }
                                else
                                {
                                    Dialog.ShowAltert(r.errors);
                                    break;
                                  
                                }
                            }
                            catch (Exception x)
                            {
                                var xMessage = $"新建失败：{x.Message}！！！";
                                LoggerHelper.Current.Error(xMessage, x);
                                Dialog.ShowAltert(xMessage);
                                break;
                            }


                        }

                        Dialog.ShowMessage("新建完成！！！");
                        OnInitPage(null);
                        _eventAggregator.GetEvent<TemplateChangedEvent>()
                        .Publish((TemplateType)_templateType);
                        break;
                    }
                    else
                    {
                        string message = "选择的模板不符合要求，请重新选择文件:\n\n";
                        if (unmatchedXmlFiles.Any())
                        {
                            message += "如下XML没有匹配的Excel:\n" + string.Join("\n", unmatchedXmlFiles.Select(Path.GetFileName)) + "\n\n";
                        }
                        if (unmatchedXlsxFiles.Any())
                        {
                            message += "如下Excel没有匹配的XML:\n" + string.Join("\n", unmatchedXlsxFiles.Select(Path.GetFileName)) + "\n\n";
                        }

                        
                        MessageBox.Show(message, "自动创建数据表模板:", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                }
                else
                {
                    break;
                }
            }

            
            //Dialog.ShowDialog("BatchTemplateSettingNew",
            //    d =>
            //    {
            //        if (d.Result == ButtonResult.OK)
            //        {
            //            OnInitPage(null);
            //            _eventAggregator.GetEvent<TemplateChangedEvent>()
            //            .Publish((TemplateType)_templateType);
            //        }
            //    });
        }

        protected override async void OnInitPage(object obj)
        {
            try
            {
                string proId = GlobalObject.CurrentProject.ProjId.ToString();
                var list = await _templateSettingService.GetTemplateLisAsync(proId);
                foreach (var item in list)
                {
                    switch (item.InOrOut)
                    {
                        case -1: item.InOrOutStr = "N/A"; break;
                        case 0: item.InOrOutStr = "输入用"; break;
                        case 1: item.InOrOutStr = "输出用"; break;
                        default:
                            break;
                    }
                }
                //list = list.Where(x => x.Type == (TemplateType)_templateType).ToList();
                DataList.Clear();
                DataList.AddRange(list);
            }
            catch (Exception x)
            {
                var xMessage = $"模板数据加载失败：{x.Message}！！！";
                LoggerHelper.Current.Error(xMessage, x);
                Dialog.ShowAltert(xMessage);
            }
        }
    }
}
